package com.knight.condition;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SimpleQueue<T> {

    Lock lock;

    int capacity;
    /** Condition for waiting takes */
    private final Condition notEmpty;

    /** Condition for waiting puts */
    private final Condition notFull;

    public SimpleQueue(int capacity) {
        this.lock = new ReentrantLock();
        this.capacity = capacity;
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

    private List<T> list = new ArrayList<>(capacity);


    public void put(T obj) {
        try {
            lock.lock();
            while (list.size() >= capacity) {
                notFull.await();
            }
            list.add(obj);
            notEmpty.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T take() {
        try {
            lock.lock();
            while (list.size() == 0) {
                notEmpty.await();
            }
            T data = list.get(0);
            list.remove(data);
            notFull.signal();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            lock.unlock();
        }

    }

}
